
<?php
namespace App\Tools;
error_reporting(0);

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;

class RabbitmqRectificationProducer
{

    /**
     * 发送 生时校正 消息到队列中
     * 实现原理：
     * 1、rabbitmq 可以针对 Queue和Message 设置  x-message-ttl 来控制消息的生存时间，如果超时，消息变为  dead letter
     * 2、rabbitmq 的queue 可以配置 x-dead-letter-exchange 和 x-dead-letter-routing(可选)两个参数，来控制队列出现  dead letter 的时候，重新发送消息的目的地
     * @param $delaySecond
     * @param $jobData
     */
    public static function sendMessage($delaySecond, $jobData)
    {

        //连接Rabbitmq，设置连接参数
        $connection = new AMQPStreamConnection(config('rabbitmq.host'), config('rabbitmq.port'), config('rabbitmq.username'), config('rabbitmq.password'));
        $channel    = $connection->channel();

        //交换机的名字
        $rectification_exchange_name = 'rectification_exchange_delay_' . $delaySecond . '_second';
        //队列的名字
        $rectification_queue_name = 'rectification_queue_delay_' . $delaySecond . '_second';
        //延迟时间
        $expiration = $delaySecond * 1000;

        $channel->exchange_declare('delay_rectification_exchange', 'direct', false, false, false);
        $channel->exchange_declare($rectification_exchange_name, 'direct', false, false, false);

        //设置队列的超时时间
        $tale = new AMQPTable();
        $tale->set('x-dead-letter-exchange', 'delay_rectification_exchange');
        $tale->set('x-dead-letter-routing-key', 'delay_rectification_exchange');
        $tale->set('x-message-ttl', $expiration);
        $channel->queue_declare($rectification_queue_name, false, true, false, false, false, $tale);
        $channel->queue_bind($rectification_queue_name, $rectification_exchange_name, '');

        $channel->queue_declare('delay_rectification_queue', false, true, false, false, false);
        $channel->queue_bind('delay_rectification_queue', 'delay_rectification_exchange', 'delay_rectification_exchange');

        $msg = new AMQPMessage(json_encode($jobData), array(
            'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
        ));

        $channel->basic_publish($msg, $rectification_exchange_name, '');
        echo date('Y-m-d H:i:s') . " [x] Sent 'Hello World!' " . PHP_EOL;

        $channel->close();
        $connection->close();
    }
}
